/************************************
BigInt
main.cpp - testing file
Calculator for large integers.
CS 133 - Parallel Programming
Professor: Adam Kaplan
Due: 6/3/2011
Collaborators:
Ben Harounian
Justin Kiang
Akhil Rangaraj
************************************/
#include "BigInt.h"
#include <iomanip>

using namespace std;

/* Main Function */
int main()
{
	/* TESTING */
	cout << "*********************TESTING*********************" << endl;

	// From String
	cout << endl << "BigInt from string" << endl;
	string value = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
	BigInt temp(value);

	cout << "This is the string: " << endl << value << endl;
	cout << "This is the string representation: " << endl << temp.toString() << endl;


	// From int
	cout << endl << "BigInt from int" << endl;	
	int bval = 123456789;
	BigInt bint(bval);

	cout << "This is the int: " << endl << bval << endl;
	cout << "This is the string representation: " << endl << bint.toString() << endl;


	// Copy constructor
	cout << endl << "BigInt Copy from previous int" << endl;	
	BigInt aint(bint);

	cout << "This is the object we copied from in string representation: " << endl << bint.toString() << endl;
	cout << "This is the current object in string representation: " << endl << aint.toString() << endl;


	// Equality check
	cout << endl << "Checking if the two previous ints are equal" << endl;	
	cout << "Are the two objects equal? " << (aint == bint ? "YES" : "NO") << endl;


	// Negation Check
	// PROBLEM HERE: The '!' operation flips the last bits 
	// ie: [00001 10111] becomes [11110 01000] when it should only be [00000 01000]
	cout << endl << "Checking Negation" << endl;	
	BigInt temps(1234567890);

	cout << "This is   temps: " << temps.toString() << endl;
	cout << "This is  !temps: " << (!temps).toString() << endl;
	cout << "This is !!temps: " << (!temps).toString() << endl;


	// Create some values
	BigInt a(123456);
	BigInt b(234567);


	// Bitwise OR check
	cout << endl << "Checking bitwise or" << endl;
	BigInt c = (a | b);
	cout << "This is a's string representation: " << a.toString() << endl;
	cout << "This is b's string representation: " << b.toString() << endl;
	cout << "This is c's string representation: " << c.toString() << endl;


	// Bitwise XOR check
	cout << endl << "Checking bitwise xor" << endl;
	BigInt d = (a ^ b);
	cout << "This is a's string representation: " << a.toString() << endl;
	cout << "This is b's string representation: " << b.toString() << endl;
	cout << "This is d's string representation: " << d.toString() << endl;


	// Bitwise AND check
	cout << endl << "Checking bitwise and" << endl;
	BigInt e = (a & b);
	cout << "This is a's string representation: " << a.toString() << endl;
	cout << "This is b's string representation: " << b.toString() << endl;
	cout << "This is e's string representation: " << e.toString() << endl;


	// Addition check
	cout << endl << "Checking addition 1" << endl;
	BigInt f = (a + b);
	cout << "This is a's bit string representation: " << a.toString() << endl;
	cout << "This is b's bit string representation: " << b.toString() << endl;
	cout << "This is f's bit string representation: " << f.toString() << endl;


	// Addition check
	cout << endl << "Checking addition 2" << endl;
	BigInt g(1048575);
	BigInt h = (g + g);
	cout << "This is g's bit string representation: " << g.toString() << endl;
	cout << "This is g's bit string representation: " << g.toString() << endl;
	cout << "This is h's bit string representation: " << h.toString() << endl;

	// Addition check
	cout << endl << "Checking addition 3" << endl;
	BigInt oneone(99999);
	BigInt onetwo(00001);
	BigInt totalonetwo = (oneone + onetwo);
	cout << "This is one's bit string representation: " << oneone.toString() << endl;
	cout << "This is two's bit string representation: " << onetwo.toString() << endl;
	cout << "This is total's bit string representation: " << totalonetwo.toString() << endl;

	// Addition check
	cout << endl << "Checking addition 4" << endl;
	BigInt bb(9);
	BigInt bbb(1);
	BigInt bbbb;
	for (int i = 0; i < 9; i++)
	{
		bbbb += bbb;
	}// End for
	cout << "This is one's bit string representation: " << bb.toString() << endl;
	cout << "This is two's bit string representation: " << bbb.toString() << endl;
	cout << "This is total's bit string representation: " << bbbb.toString() << endl;


	// Multiplication check
	cout << endl << "Checking multiplication 1" << endl;
	BigInt twoone(9);
	BigInt twotwo(1);
	BigInt totaltwotwo = (twoone * twotwo);
	cout << "This is one's bit string representation: " << twoone.toString() << endl;
	cout << "This is two's bit string representation: " << twotwo.toString() << endl;
	cout << "This is total's bit string representation: " << totaltwotwo.toString() << endl;


	// Multiplication check
	cout << endl << "Checking multiplication 2" << endl;
	BigInt twoo("11");
	BigInt twot(4);
	BigInt totalt = (twoo * twot);
	cout << "This is one's bit string representation: " << twoo.toString() << endl;
	cout << "This is two's bit string representation: " << twot.toString() << endl;
	cout << "This is total's bit string representation: " << totalt.toString() << endl;


	// Multiplication check
	cout << endl << "Checking multiplication 3" << endl;
	BigInt aa(1234);
	BigInt aaa(30);
	BigInt aaaa = (aa * aaa);
	cout << "This is one's bit string representation: " << aa.toString() << endl;
	cout << "This is two's bit string representation: " << aaa.toString() << endl;
	cout << "This is total's bit string representation: " << aaaa.toString() << endl;




	// Delete memory
	/* GIVES AN ERROR */
	/*
		temp.~BigInt();
		bint.~BigInt();
		aint.~BigInt();
		temps.~BigInt();
		a.~BigInt();
		b.~BigInt();
		c.~BigInt();
		d.~BigInt();
		e.~BigInt();
	*/

	/* End Testing */
	cout << "*******************END TESTING*******************" << endl;

	return 0;
}// End main function